﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SimpleCodeGenerator.Schema;
using SimpleCodeGenerator.Utility;

namespace SimpleCodeGenerator.Generators
{
    class ServiceLayerGenerator : GeneratorBase
    {
        public override void Generate(TableSchema table)
        {
            var sResult = new MyStringBuilder();

            #region common:copyright/ using block
            BuildCopyRight(sResult);
            BuildCommonUsingBlock(sResult);
            BuildMoreUsingBlock(sResult, "Vancl.CMS.Data" + Namespace);//add Data reference
            BuildMoreUsingBlock(sResult, "Vancl.CMS.Model");//add Model reference
            BuildMoreUsingBlock(sResult, "Vancl.CMS.Model" + Namespace);//add Model reference
            sResult.AppendLine();
            #endregion

            string datalayerName = table.Code + "Service";

            //namespace start
            #region namespace
            sResult.AppendFormat("namespace Vancl.CMS.Service{0}", Namespace)
                .AppendLine();
            sResult.AppendLine("{");
            #endregion

            sResult.IncreaseIndent();//increase indent for class signature
            //class signature
            #region class signature
            //summary
            BuildRemark(sResult, table.Comment + "的业务逻辑层");
            sResult.AppendFormat("public static class {0}", datalayerName).AppendLine();
            sResult.AppendLine("{");//class start 
            #endregion

            sResult.IncreaseIndent();
            //genereate insert method
            GenerateInsertMethod(sResult, table);
            sResult.AppendLine();
            sResult.DecreaseIndent();

            sResult.IncreaseIndent();
            //generate update method
            GenerateUpdateMethod(sResult, table);
            sResult.AppendLine();
            sResult.DecreaseIndent();

            sResult.IncreaseIndent();
            GenerateGetItemMethod(sResult, table);
            sResult.AppendLine();
            sResult.DecreaseIndent();

            //genereate delete method
            sResult.IncreaseIndent();
            GenerateDeleteMethod(sResult, table);
            sResult.AppendLine();
            sResult.DecreaseIndent();

            sResult.IncreaseIndent();
            GenerateSearchMethod(sResult, table);
            sResult.AppendLine();
            sResult.DecreaseIndent();

            sResult.AppendLine("}");//class end

            sResult.DecreaseIndent();//decrease indent for class
            sResult.AppendLine("}");//namespace end

            Save(datalayerName, sResult.ToString());
        }

        private void GenerateGetItemMethod(MyStringBuilder output, TableSchema table)
        {
            #region method signature
            BuildRemark(output, "按主键获取一条记录");
            foreach (var key in table.PrimaryKeyColumns)
            {
                BuildParamRemark(output, key.Code.FirstLetterToLower(), key.Comment);
            }
            BuildReturnRemark(output, "存在该条记录则返回" + table.Code + "Info 类的实例，否则返回null");

            //method signature
            output.AppendFormat("public static {0} GetItem(", table.Code + "Info");

            //method parameters
            foreach (var key in table.PrimaryKeyColumns)
            {
                output.AppendNoLineFormat("{0} {1},", key.DataType, key.Code.FirstLetterToLower());
            }
            output.RemoveFromLast(1);
            output.Append(")")
                .AppendLine();
            #endregion

            output.AppendLine("{");//method start

            output.IncreaseIndent();//method start
            output.AppendFormat("return {0}Data.GetItem(", table.Code);
            //method parameters
            foreach (var key in table.PrimaryKeyColumns)
            {
                output.AppendNoLineFormat("{0},", key.Code.FirstLetterToLower());
            }
            output.RemoveFromLast(1);
            output.Append(");");

            output.DecreaseIndent();//method end
            output.AppendLine();
            output.AppendLine("}");//method end
        }



        void GenerateInsertMethod(MyStringBuilder output, TableSchema table)
        {
            string paramName = table.Code.FirstLetterToLower();
            #region class signature
            BuildRemark(output, "插入数据库");
            BuildParamRemark(output, paramName, table.Comment + "实例");

            //method signature
            output.AppendFormat("public static int Insert({0}Info {1})", table.Code, paramName)
                .AppendLine();
            #endregion

            output.AppendLine("{");//method start

            output.IncreaseIndent();//increaset indent for method body

            output.AppendLine(string.Format("return {0}Data.Insert({1});",table.Code,paramName));

            output.DecreaseIndent();//decrease indent for method body

            output.AppendLine("}");//method end
        }

        void GenerateDeleteMethod(MyStringBuilder output, TableSchema table)
        {
            #region method signature
            BuildRemark(output, "按主键删除记录");
            foreach (var key in table.PrimaryKeyColumns)
            {
                BuildParamRemark(output, key.Code.FirstLetterToLower(), key.Comment);
            }
            BuildReturnRemark(output, "受影响的条数");

            //method signature
            output.AppendFormat("public static int Delete(");

            //method parameters
            foreach (var key in table.PrimaryKeyColumns)
            {
                output.AppendNoLineFormat("{0} {1},", key.DataType, key.Code.FirstLetterToLower());
            }
            output.RemoveFromLast(1);
            output.Append(")");
            output.AppendLine();
            #endregion

            output.AppendLine("{");//method start
            output.IncreaseIndent();//increate indent for method body

            output.AppendFormat("return {0}Data.Delete(", table.Code);
            //method parameters
            foreach (var key in table.PrimaryKeyColumns)
            {
                output.AppendNoLineFormat("{0},", key.Code.FirstLetterToLower());
            }
            output.RemoveFromLast(1);
            output.Append(");");

            output.DecreaseIndent();//decrease indent for method body
            output.AppendLine("");//method end
            output.AppendLine("}");//method end
        }

        void GenerateUpdateMethod(MyStringBuilder output, TableSchema table)
        {
            #region method signature
            BuildRemark(output, "更新记录");
            BuildParamRemark(output, table.Code.FirstLetterToLower(), "实体对象");
            BuildReturnRemark(output, "受影响的条数");

            //method signature
            output.AppendFormat("public static int Update({0} {1})", table.Code + "Info", table.Code.FirstLetterToLower())
                .AppendLine();
            #endregion

            output.AppendLine("{");//method start

            output.IncreaseIndent(); //increase indent for method body

            //return 
            output.AppendLine(string.Format("return {0}Data.Update({1});", table.Code, table.Code.FirstLetterToLower()));
            output.DecreaseIndent(); //decrease indent for method body

            output.AppendLine("}");//method end
        }

        void GenerateSearchMethod(MyStringBuilder output, TableSchema table)
        {
            #region method signature
            BuildRemark(output, "搜索数据表中的记录");
            BuildParamRemark(output, "pageIndex", "当前显示第几页(从1开始)");
            BuildParamRemark(output, "pageSize", "每页显示条数");
            BuildParamRemark(output, "options", "搜索条件，请参照SearchOptions类的各个字段说明具体使用");
            BuildParamRemark(output, "isAscending", "是否按照主键升序排序，默认为升序排列");
            BuildReturnRemark(output, "记录列表");
            //method signature
            output.AppendFormat("public static IPageOfList<{0}Info> Search(int pageIndex, int pageSize,Vancl.CMS.Data{1}.{0}Data.SearchOptions options,bool isAscending = true)", table.Code, Namespace);
            #endregion

            output.AppendLine();
            output.AppendLine("{");

            output.IncreaseIndent();//increase indent for method body
            output.AppendLine(string.Format("return {0}Data.Search(pageIndex, pageSize,options,isAscending);", table.Code));

            output.DecreaseIndent();//increase indent for method body
            output.AppendLine("}");
        } 
    }
}
